﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;

namespace LINQPadLogParser
{
  public sealed class IPEndPointWrapper : IFormattable
  {
    private readonly int _id;

    private IPEndPoint _endPoint;
    private string _ip;
    private string _port;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public IPEndPointWrapper(int id)
    {
      _id = id;
    }

    private string IPString
    {
      [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _ip ?? (_ip = LogParserDataContext.LineManager.GetValue(_id, W3CColumn.ServerIP)); }
    }

    private string PortString
    {
      [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _port ?? (_port = LogParserDataContext.LineManager.GetValue(_id, W3CColumn.ServerPort)); }
    }

    private IPEndPoint EndPoint
    {
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      get
      {
        if (_endPoint == null)
        {
          string ip = IPString;
          string port = PortString;
          _endPoint = ip == null ? new IPEndPoint(0, 0) : new IPEndPoint(IPAddress.Parse(ip), port != null ? int.Parse(port) : 80);
        }
        return _endPoint;
      }
    }

    public AddressFamily AddressFamily
    {
      [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return EndPoint.AddressFamily; }
    }

    public IPAddress Address
    {
      [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return EndPoint.Address; }
    }

    public int Port
    {
      [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return EndPoint.Port; }
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public string ToString(string format, IFormatProvider formatProvider)
    {
      return ToString();
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public override string ToString()
    {
      if (_endPoint != null)
        return _endPoint.ToString();
      string ip = IPString;
      if (ip == null)
        return string.Empty;
      return ip + ":" + (PortString ?? "80");
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public SocketAddress Serialize()
    {
      return EndPoint.Serialize();
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public EndPoint Create(SocketAddress socketAddress)
    {
      return EndPoint.Create(socketAddress);
    }
  }
}